package it.unibo.deis.lia.mmhc.spm;

import it.unibo.deis.lia.mmhc.nip.NetworkInterfaceProvider;
import it.unibo.deis.lia.mmhc.sfm.FindedService;
import it.unibo.deis.lia.mmhc.sfm.ServiceAttivation;

import java.io.ObjectOutputStream;
import java.net.BindException;

import java.net.Socket;
import java.util.Vector;

public class ServiceManager {

	private Vector<String> servicePathServers;
	private static ServiceManager serviceManager = null;

	private int servicePort = 2500;// porta su cui vengo creati i path per i
									// servizi

	public ServiceManager() {
		super();
		this.servicePathServers = new Vector<String>();
	}

	public static ServiceManager getInstance() {
		if (serviceManager == null)
			serviceManager = new ServiceManager();
		return serviceManager;
	}

	public void addServicePathServer(String address) {
		if (!vectorContains(servicePathServers, address)) {
			ServicePathServer serverPath = new ServicePathServer(address,
					servicePort);
			serverPath.start();
		}
	}

	public void serviceAttivation(FindedService service) throws Exception {
		ServiceAttivation attivation = new ServiceAttivation(-1, null,
				NetworkInterfaceProvider.getMyUniversalName(),
				((Service) service.getOgg()).getFornitore(), (Service) service
						.getOgg(), service.getHopGoSequence(), service
						.getHopBackSequence());
		// System.err.println("andata"+attivation.getNextBackHop());
		int attempts = 5;
		String hop = attivation.getNextGoHop();
		Socket out = null;
		do {
			try {
				System.err.println("provo aprire socket su indirizzo " + hop
						+ "porta" + 2500);
				out = new Socket(hop, 2401);
			} catch (BindException e) {
			} catch (Exception e) {
				Thread.sleep(1500);
				attempts--;
				if (attempts == 0)
					throw e;
				System.err
						.println("Impossibile aprire o trovare socket di risposta "
								+ e);
			}
		} while (attempts > 0 && out == null);
		ObjectOutputStream oos = new ObjectOutputStream(out.getOutputStream());
		oos.flush();
		oos.writeObject(attivation);
		System.err.println("Attivazione su porta 2401 inviata a " + hop);
		oos.flush();
		out.close();
	}

	private boolean vectorContains(Vector<String> vector, String stringa) {
		for (int i = 0; i < vector.size(); i++) {
			if (vector.elementAt(i).equalsIgnoreCase(stringa))
				return true;
		}
		return false;

	}
}
